package org.platform.service.knowledge;

import org.platform.constant.VersionConstant;
import org.platform.dao.mapper.FdKbTestchannelMapper;
import org.platform.dao.mapper.FdKbTestmainMapper;
import org.platform.dao.mapper.FdKbTestparamsMapper;
import org.platform.dao.mapper.FdKbTesttemplateMapper;
import org.platform.mo.csmo.cmd10009.TestGroupQueryRequestParam;
import org.platform.mo.csmo.cmd10009.TestGroupQueryResponseParam;
import org.platform.mo.csmo.cmd10010.TestGroupAddRequestParam;
import org.platform.mo.csmo.cmd10010.TestGroupAddResponseParam;
import org.platform.mo.csmo.cmd10011.TestGroupDelRequestParam;
import org.platform.mo.csmo.cmd10011.TestGroupDelResponseParam;
import org.platform.mo.csmo.cmd10012.TestGroupModifyRequestParam;
import org.platform.mo.csmo.cmd10012.TestGroupModifyResponseParam;
import org.platform.mo.csmo.cmd10013.QueryTestGroupRequestParam;
import org.platform.mo.csmo.cmd10013.QueryTestGroupResponseParam;
import org.platform.mo.csmo.common.KB_TestParam;
import org.platform.mo.csmo.common.KB_TestTemplate;
import org.platform.mo.csmo.common.LoopTests;
import org.platform.mo.csmo.common.TestChannelBean;
import org.platform.mo.db.FdKbTestchannel;
import org.platform.mo.db.FdKbTestmain;
import org.platform.mo.db.FdKbTestparams;
import org.platform.mo.db.FdKbTesttemplate;
import org.platform.processor.diagnose.DiagnoseTaskProcessor;
import org.platform.processor.knowledge.TestProcesor;
import org.platform.service.IBaseService;
import org.platform.tool.helper.LogHelper;
import org.platform.tool.util.BeansUtils;
import org.platform.tool.util.ComUtils;
import org.platform.tool.util.JsonUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.util.List;

/**
 * @author FengJie
 * @date 2018/4/16
 */
@Service
public class TestServiceImpl implements IBaseService {
    @Autowired
    private TestProcesor testProcesor;
    /**
     * test模板
     */
    @Autowired
    private FdKbTesttemplateMapper testTemplateMapper;
    /**
     * 测试知识主表
     */
    @Autowired
    private FdKbTestmainMapper testMainMapper;
    /**
     * 测试通道知识表
     */
    @Autowired
    private FdKbTestchannelMapper testChannelMapper;
    /**
     * 测试参数表
     */
    @Autowired
    private FdKbTestparamsMapper testParamsMapper;
    @Autowired
    private LogHelper logHelper;
    @Autowired
    private DiagnoseTaskProcessor taskProcessor;

    /**
     * 查询测试模板集合（10009）
     */
    public TestGroupQueryResponseParam getTestGroup(TestGroupQueryRequestParam requestParam) {
        TestGroupQueryResponseParam responseParam = new TestGroupQueryResponseParam();
        FdKbTesttemplate testTemplate = testProcesor.getTestTemplate(requestParam.getKnowledgeID(), requestParam.getStation());
        BeanUtils.copyProperties(testTemplate, responseParam.getTestTemplate());

        Example example = new Example(FdKbTestmain.class);
        example.createCriteria().andEqualTo("knowledgeid", requestParam.getKnowledgeID())
                .andEqualTo("station", requestParam.getStation());
        List<FdKbTestmain> mainList = testMainMapper.selectByExample(example);

        KB_TestParam testParam = new KB_TestParam();
        if (!mainList.isEmpty()) {
            BeanUtils.copyProperties(mainList.get(0), testParam);
        }
        responseParam.getTestTemplate().setTestParam(testParam);
        return responseParam;
    }

    /**
     * 增加测试模板（10010）
     */
    @Transactional(rollbackFor = Exception.class)
    public TestGroupAddResponseParam addTestGroup(TestGroupAddRequestParam requestParam) {
        try {
            KB_TestTemplate testTemplate = requestParam.getTestTemplate();
            KB_TestParam testParam = testTemplate.getTestParam();

            //先判断知识主表是否需要新增
            String knowledgeId = ComUtils.objectToString(testTemplate.getKnowledgeid());
            if (testMainMapper.selectByPrimaryKey(knowledgeId) == null) {
                //测试主表
                FdKbTestmain testMain = new FdKbTestmain();
                BeanUtils.copyProperties(testParam, testMain);
                testMain.setId(knowledgeId);
                testMain.setTestdesc(testTemplate.getLooptestname());
                testMain.setVersion(VersionConstant.DEFAULT_VERSION);
                //TODO 这里 [超时时间] 需要从配置文件中读取
                testMain.setCosttime(0L);
                testMainMapper.insertSelective(testMain);
            }

            //保存模板表
            setUnUse(testTemplate);
            FdKbTesttemplate template = new FdKbTesttemplate();
            BeanUtils.copyProperties(testTemplate, template);
            String templateId = knowledgeId + "_" + testTemplate.getTemplateid();
            template.setId(templateId);
            template.setVersion(VersionConstant.DEFAULT_VERSION);
            testTemplateMapper.insertSelective(template);
            saveChannelAndParams(testTemplate);
            logHelper.normal("增加测试模板【成功】", null, null);
        } catch (RuntimeException | IOException r) {
            logHelper.error("增加测试模板【失败】", null, null, r);
        }
        return new TestGroupAddResponseParam();
    }

    /**
     * 删除测试模板（10011）
     */
    @Transactional(rollbackFor = Exception.class)
    public TestGroupDelResponseParam delTestGroup(TestGroupDelRequestParam requestParam) {
        try {
            Example example = new Example(FdKbTesttemplate.class);
            example.createCriteria()
                    .andEqualTo("station", requestParam.getStation())
                    .andEqualTo("templateid", requestParam.getTemplateId());
            testTemplateMapper.deleteByExample(example);
            testChannelMapper.deleteByExample(example);
            testParamsMapper.deleteByExample(example);

            logHelper.normal("删除测试模板【成功】", null, null);
        } catch (RuntimeException r) {
            logHelper.error("删除测试模板【失败】", null, null, r);
        }
        return new TestGroupDelResponseParam();
    }

    /**
     * 修改测试模板（10012）
     */
    @Transactional(rollbackFor = Exception.class)
    public TestGroupModifyResponseParam modifyTestGroup(TestGroupModifyRequestParam requestParam) throws IOException {
        try {
            KB_TestTemplate testTemplate = requestParam.getTestTemplate();

            //模板表  如果当前状态是启用状态,则把所有的模板设置为不可用状态
            setUnUse(testTemplate);
            FdKbTesttemplate template = new FdKbTesttemplate();
            BeanUtils.copyProperties(testTemplate, template);
            testTemplateMapper.updateByPrimaryKeySelective(template);

            Example example = new Example(FdKbTesttemplate.class);
            example.createCriteria()
                    .andEqualTo("station", testTemplate.getStation())
                    .andEqualTo("templateid", testTemplate.getTemplateid());
            testChannelMapper.deleteByExample(example);
            testParamsMapper.deleteByExample(example);
            saveChannelAndParams(testTemplate);


            logHelper.normal("修改测试模板【成功】", null, null);
        } catch (RuntimeException r) {
            logHelper.error("修改测试模板【失败】", null, null, r);
        }
        return new TestGroupModifyResponseParam();
    }

    /**
     * 查询所有的模板集合
     *
     * @param requestParam
     * @return
     */
    public QueryTestGroupResponseParam queryTestGroup(QueryTestGroupRequestParam requestParam) {
        QueryTestGroupResponseParam responseParam = new QueryTestGroupResponseParam();

        Example example = new Example(FdKbTesttemplate.class);
        example.createCriteria()
                .andEqualTo("knowledgeid", requestParam.getKnowledgeID())
                .andEqualTo("station", requestParam.getStation());
        List<FdKbTesttemplate> testTemplateList = testTemplateMapper.selectByExample(example);
        List<KB_TestTemplate> list = BeansUtils.copyListProperties(testTemplateList, KB_TestTemplate.class);
        responseParam.setTestTemplateList(list);
        return responseParam;
    }

    /**
     * 设置为不可用状态
     *
     * @param testTemplate 模板
     */
    private void setUnUse(KB_TestTemplate testTemplate) {
        //  如果当前状态是启用状态,则把所有的模板设置为不可用状态
        if (testTemplate.getUseby().equals(VersionConstant.USE)) {
            FdKbTesttemplate template = new FdKbTesttemplate();
            Example example = new Example(FdKbTesttemplate.class);
            example.createCriteria()
                    .andEqualTo("knowledgeid", testTemplate.getKnowledgeid())
                    .andEqualTo("station", testTemplate.getStation());
            template.setUseby(VersionConstant.UNUSE);
            testTemplateMapper.updateByExampleSelective(template, example);
        }
    }

    /**
     * 保存通道表表和参数表
     *
     * @param testTemplate
     * @throws IOException
     */
    private void saveChannelAndParams(KB_TestTemplate testTemplate) throws IOException {
        //保存通道和参数表
        LoopTests loopTests = JsonUtils.jsonToBean(testTemplate.getTestparms(), LoopTests.class, true);
        List<TestChannelBean> channelBeanList = loopTests.getTestChannelBeanList();
        for (TestChannelBean channel : channelBeanList) {
            FdKbTestchannel testChannel = new FdKbTestchannel();
            String channelId = testTemplate.getId() + "_" + channel.getNumber();
            testChannel.setId(channelId);
            testChannel.setChannelid(ComUtils.integerToStr(channel.getNumber()));
            testChannel.setTemplateid(testTemplate.getTemplateid());
            testChannel.setMainid(ComUtils.objectToString(testTemplate.getKnowledgeid()));
            testChannel.setKnowledgeid(testTemplate.getKnowledgeid());
            testChannel.setTesttype(testTemplate.getTesttype());
            testChannel.setStation(testTemplate.getStation());
            testChannel.setVersion(VersionConstant.DEFAULT_VERSION);
            testChannelMapper.insertSelective(testChannel);

            FdKbTestparams fdTestParams = new FdKbTestparams();
            BeanUtils.copyProperties(testChannel, fdTestParams);
            fdTestParams.setDevlink(taskProcessor.getDeviceLink(channel.getDeviceLinkList()));
            fdTestParams.setTestparms(taskProcessor.getDeviceParam(channel.getDeviceParamList()));
            testParamsMapper.insertSelective(fdTestParams);
        }
    }
}
